package eu.tanov.epf.pv.types.project.ui.pages;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.authoring.ui.editors.MethodElementEditor;
import org.eclipse.epf.authoring.ui.forms.CustomCategoryDescriptionPage;
import org.eclipse.epf.library.edit.command.IActionManager;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.Section;
import org.eclipse.epf.uma.UmaFactory;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.util.ContentDescriptionFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.editor.FormEditor;

import eu.tanov.epf.pv.types.project.common.util.ProjectFactorConstants;
import eu.tanov.epf.pv.types.project.ui.i18n.ProjectUIResources;
import eu.tanov.epf.pv.types.project.ui.provider.ProjectItemProvider;
import eu.tanov.epf.pv.ui.common.util.EditorHelper;
import eu.tanov.epf.pv.ui.common.util.FormHelper;

public class ProjectDescriptionPage extends CustomCategoryDescriptionPage {

	private Map<String,Combo> combos = new HashMap<String,Combo>();

	private static final String classNameForFormTitle = ProjectUIResources.project_text;

	/**
	 * because disposed is private in parent
	 */
	private boolean disposed;

	public ProjectDescriptionPage(FormEditor editor) {
		super(editor);
		EditorHelper.updateTitleImage(editor,
				ProjectItemProvider.getProjectImage());
	}

	@Override
	public void init(IEditorSite site, IEditorInput input) {
		super.init(site, input);

		// without variability - if on - it searches in custom categories, not
		// in Projects
		// but it is not used - so disable
		this.variabilitySectionOn = false;

		// issue #170
		this.iconSectionOn = false;
	}

	@Override
	public void dispose() {
		super.dispose();
		disposed = true;
	}

	@Override
	protected void createFormContent(IManagedForm managedForm) {
		super.createFormContent(managedForm);

		FormHelper.updateFormText(form, classNameForFormTitle, contentElement);
	}

	@Override
	protected void addListeners() {
		super.addListeners();

		// because setFormTextWithVariableInfo() is private
		FormHelper.replaceLastListener(form.getParent(), SWT.Activate,
				new Listener() {
					public void handleEvent(Event event) {
						if (disposed) {
							return;
						}

						refresh(!TngUtil.isLocked(methodElement));
						FormHelper.updateFormText(form, classNameForFormTitle,
								contentElement);

						// do refresh variability and copyright viewer
						if (variabilitySectionOn)
							base_viewer.refresh();
						if (versionSectionOn)
							copyright_viewer.refresh();
					}
				}, "org.eclipse.epf.authoring.ui.forms.DescriptionFormPage");

		// add combo listeners
		for (final Entry<String,Combo>entry : combos.entrySet()) {
			final Combo comboWithListener = entry.getValue();
			comboWithListener.addModifyListener(modelModifyListener);
			comboWithListener.addSelectionListener(new SelectionListener() {

				@Override
				public void widgetSelected(SelectionEvent e) {
					String value = comboWithListener.getText();
					// XXX method section
					List<Section> sections = contentElement.getPresentation()
							.getSections();
					Section section = UmaFactory.eINSTANCE.createSection();
					section.setSectionName(entry.getKey());
					section.setName(value);
					setSection(sections, section);
					// HAX
					actionMgr.doAction(IActionManager.SET, methodUnit,
							UmaPackage.eINSTANCE.getMethodUnit_ChangeDate(),
							new Date(), -1);
				}

				@Override
				public void widgetDefaultSelected(SelectionEvent e) {
				}
			});
		}

	}

	/*
	 * Copy/pasted in order to save custom title because
	 * setFormTextWithVariableInfo() is private
	 */
	@Override
	protected boolean changeElementName(String name) {
		boolean success = actionMgr.doAction(IActionManager.SET, methodElement,
				UmaPackage.eINSTANCE.getNamedElement_Name(), name, -1);
		if (!success) {
			return false;
		}
		if (methodElement instanceof MethodConfiguration) {
			Resource resource = methodElement.eResource();
			if (resource != null) {
				((MethodElementEditor) getEditor())
						.addResourceToAdjustLocation(resource);
			}
		}
		if (ContentDescriptionFactory.hasPresentation(methodElement)) {
			Resource contentResource = contentElement.getPresentation()
					.eResource();
			if (contentResource != null) {
				((MethodElementEditor) getEditor())
						.addResourceToAdjustLocation(contentResource);
			}
		}
		FormHelper.updateFormText(form, classNameForFormTitle, contentElement);
		ctrl_name.setText(name);

		return true;
	}

	/*
	 * Copy/pasted in order to save custom title because
	 * setFormTextWithVariableInfo() is private
	 */
	@Override
	public void refreshName(String newName) {
		if (newName != null) {
			if ((ctrl_name != null) && !(ctrl_name.isDisposed())) {
				if (modelModifyListener != null) {
					ctrl_name.removeModifyListener(modelModifyListener);
					ctrl_name.setText(newName);
					ctrl_name.addModifyListener(modelModifyListener);
				} else {
					ctrl_name.setText(newName);
				}
				FormHelper.updateFormText(form, classNameForFormTitle,
						contentElement);
			}
		}
	}

	@Override
	public void loadSectionDescription() {
		this.generalSectionDescription = ProjectUIResources.project_generalInfoSection_desc;
		this.detailSectionDescription = ProjectUIResources.project_detailSection_desc;
		this.variabilitySectionDescription = ProjectUIResources.project_variabilitySection_desc;
		this.versionSectionDescription = ProjectUIResources.project_versionInfoSection_desc;
		this.iconSectionDescription = ProjectUIResources.project_IconSection_desc;
	}

	@Override
	protected void createDetailSectionContent() {
		super.createDetailSectionContent();
		String methodSelection = "";
		// XXX method section
		List<Section> sections = contentElement.getPresentation().getSections();

		Map<String, String[]> map = ProjectFactorConstants.getMap();
		for (final Entry<String, String[]> entry : map.entrySet()) {
			final Combo comboWithListener = createComboWithLabel(toolkit,
					detailComposite, entry.getKey().replace("_", " "));
			combos.put(entry.getKey(),comboWithListener);
			GridData data = new GridData(400, 40);
			data.horizontalSpan = 2;
			comboWithListener.setLayoutData(data);

			// XXX method section
			methodSelection = getSectionName(sections, entry.getKey());
			comboWithListener.setItems(entry.getValue());
			comboWithListener.setText(methodSelection);
		}
	}

	private String getSectionName(List<Section> sections, String sectionName) {
		Section section = getSection(sections, sectionName);
		if (section == null) {
			return "";
		}

		return section.getName();
	}

	private Section getSection(List<Section> sections, String sectionName) {
		for (int i = 0; i < sections.size(); ++i) {
			if (sections.get(i).getSectionName().equals(sectionName)) {
				return sections.get(i);
			}
		}
		return null;
	}

	private void setSection(List<Section> sections, Section newSection) {
		for (int i = 0; i < sections.size(); ++i) {
			if (sections.get(i).getSectionName()
					.equals(newSection.getSectionName())) {
				sections.remove(i);
				break;
			}
		}

		sections.add(newSection);
	}

}
